/**
 * 模型管理器类
 * 负责GLTF模型的加载和建筑物替换
 */

// 引入Three.js相关库
import * as THREE from 'three';
import { GLTFLoader } from 'three/examples/jsm/loaders/GLTFLoader';

class ModelManager {
  /**
   * 构造函数
   * @param {Object} map 地图实例
   */
  constructor(map) {
    this.map = map;                 // 地图实例
    this.scene = null;              // Three.js场景
    this.camera = null;             // Three.js相机
    this.renderer = null;           // Three.js渲染器
    this.models = new Map();        // 模型缓存
    this.replacedBuildings = new Map(); // 已替换的建筑物
    this.gltfLoader = null;         // GLTF加载器
    this.animationFrameId = null;   // 动画帧ID
    
    // 初始化Three.js
    this.initThreeJS();
  }

  /**
   * 初始化Three.js
   */
  initThreeJS() {
    try {
      // 创建场景
      this.scene = new THREE.Scene();
      
      // 创建相机
      this.camera = new THREE.PerspectiveCamera(
        75,                // 视野角度
        window.innerWidth / window.innerHeight, // 长宽比
        0.1,               // 近平面
        1000                // 远平面
      );
      this.camera.position.set(0, 5, 10);
      this.camera.lookAt(0, 0, 0);
      
      // 创建渲染器
      this.renderer = new THREE.WebGLRenderer({
        alpha: true,       // 透明背景
        antialias: true    // 抗锯齿
      });
      this.renderer.setSize(window.innerWidth, window.innerHeight);
      this.renderer.setPixelRatio(window.devicePixelRatio);
      
      // 添加灯光
      const ambientLight = new THREE.AmbientLight(0xffffff, 0.6);
      this.scene.add(ambientLight);
      
      const directionalLight = new THREE.DirectionalLight(0xffffff, 0.8);
      directionalLight.position.set(5, 10, 7.5);
      this.scene.add(directionalLight);
      
      // 创建GLTF加载器
      this.gltfLoader = new GLTFLoader();
      
      console.log('Three.js初始化成功');
    } catch (error) {
      console.error('Three.js初始化失败:', error);
      throw error;
    }
  }

  /**
   * 预加载模型
   * @param {String} modelUrl 模型URL
   * @returns {Promise} 加载完成的Promise
   */
  async preloadModel(modelUrl) {
    return new Promise((resolve, reject) => {
      // 检查模型是否已加载
      if (this.models.has(modelUrl)) {
        resolve(this.models.get(modelUrl));
        return;
      }
      
      // 加载模型
      this.gltfLoader.load(
        modelUrl,
        (gltf) => {
          console.log('模型加载成功:', modelUrl);
          // 缓存模型
          this.models.set(modelUrl, gltf);
          resolve(gltf);
        },
        (progress) => {
          // 加载进度
          console.log('模型加载进度:', Math.round((progress.loaded / progress.total) * 100) + '%');
        },
        (error) => {
          console.error('模型加载失败:', error);
          reject(error);
        }
      );
    });
  }

  /**
   * 替换建筑物为GLTF模型
   * @param {Object} building 建筑物对象
   * @param {String} modelUrl 模型URL
   * @returns {Promise} 替换完成的Promise
   */
  async replaceBuilding(building, modelUrl) {
    return new Promise(async (resolve, reject) => {
      try {
        // 获取建筑物位置
        const position = this.getBuildingPosition(building);
        
        // 加载模型（如果未预加载）
        let gltf;
        if (this.models.has(modelUrl)) {
          gltf = this.models.get(modelUrl);
        } else {
          gltf = await this.preloadModel(modelUrl);
        }
        
        // 克隆模型，避免修改原始模型
        const model = gltf.scene.clone();
        
        // 调整模型位置、旋转和缩放
        this.adjustModelTransform(model, building);
        
        // 将模型添加到场景
        this.scene.add(model);
        
        // 记录替换信息
        this.replacedBuildings.set(building.id, {
          building,
          model,
          originalVisible: building.visible // 保存原始可见性
        });
        
        // 隐藏原始建筑物
        this.hideOriginalBuilding(building);
        
        // 开始渲染
        if (!this.animationFrameId) {
          this.startRendering();
        }
        
        resolve();
      } catch (error) {
        console.error('替换建筑物失败:', error);
        reject(error);
      }
    });
  }

  /**
   * 恢复原始建筑物
   * @param {String} buildingId 建筑物ID
   * @returns {Promise} 恢复完成的Promise
   */
  async restoreBuilding(buildingId) {
    return new Promise((resolve, reject) => {
      try {
        // 检查建筑物是否已被替换
        if (!this.replacedBuildings.has(buildingId)) {
          reject(new Error('建筑物未被替换'));
          return;
        }
        
        const replacedInfo = this.replacedBuildings.get(buildingId);
        
        // 从场景中移除模型
        this.scene.remove(replacedInfo.model);
        
        // 恢复原始建筑物可见性
        this.showOriginalBuilding(replacedInfo.building);
        
        // 移除替换记录
        this.replacedBuildings.delete(buildingId);
        
        // 如果没有替换的建筑物，停止渲染
        if (this.replacedBuildings.size === 0) {
          this.stopRendering();
        }
        
        resolve();
      } catch (error) {
        console.error('恢复建筑物失败:', error);
        reject(error);
      }
    });
  }

  /**
   * 获取建筑物位置
   * @param {Object} building 建筑物对象
   * @returns {Object} 位置对象
   */
  getBuildingPosition(building) {
    // 在实际应用中，这里需要从腾讯地图API获取建筑物的经纬度和高度信息
    // 然后转换为Three.js中的坐标
    // 这里简化处理，假设已经有了建筑物的位置信息
    return {
      x: 0,
      y: 0,
      z: 0
    };
  }

  /**
   * 调整模型变换（位置、旋转、缩放）
   * @param {Object} model Three.js模型对象
   * @param {Object} building 建筑物对象
   */
  adjustModelTransform(model, building) {
    // 设置模型位置
    const position = this.getBuildingPosition(building);
    model.position.set(position.x, position.y, position.z);
    
    // 设置模型旋转
    // 根据建筑物朝向调整，这里简化处理
    model.rotation.set(0, 0, 0);
    
    // 设置模型缩放
    // 根据建筑物实际大小调整，这里简化处理
    const scale = 1.0;
    model.scale.set(scale, scale, scale);
  }

  /**
   * 隐藏原始建筑物
   * @param {Object} building 建筑物对象
   */
  hideOriginalBuilding(building) {
    // 在实际应用中，这里需要调用腾讯地图API隐藏原始建筑物
    // 这里简化处理
    console.log('隐藏原始建筑物:', building.id);
  }

  /**
   * 显示原始建筑物
   * @param {Object} building 建筑物对象
   */
  showOriginalBuilding(building) {
    // 在实际应用中，这里需要调用腾讯地图API显示原始建筑物
    // 这里简化处理
    console.log('显示原始建筑物:', building.id);
  }

  /**
   * 开始渲染
   */
  startRendering() {
    const animate = () => {
      this.animationFrameId = requestAnimationFrame(animate);
      this.renderer.render(this.scene, this.camera);
    };
    animate();
  }

  /**
   * 停止渲染
   */
  stopRendering() {
    if (this.animationFrameId) {
      cancelAnimationFrame(this.animationFrameId);
      this.animationFrameId = null;
    }
  }

  /**
   * 销毁模型管理器，释放资源
   */
  destroy() {
    // 停止渲染
    this.stopRendering();
    
    // 恢复所有替换的建筑物
    this.replacedBuildings.forEach((info, buildingId) => {
      this.scene.remove(info.model);
      this.showOriginalBuilding(info.building);
    });
    
    // 清空缓存
    this.replacedBuildings.clear();
    this.models.clear();
    
    // 释放Three.js资源
    this.scene = null;
    this.camera = null;
    if (this.renderer) {
      this.renderer.dispose();
      this.renderer = null;
    }
    
    console.log('模型管理器资源已释放');
  }
}

export default ModelManager;